home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#45 (Jun 89)
/
Forth Code
/
Beeper INIT
next >
Wrap
Text File
|
1989-04-17
|
5KB
|
201 lines
\ INIT example which patches _GetResource
\ with a call to _Sysbeep if type=CODE id=0
\ Also patches _ExitToShell, using an absolutely
\ AWFUL hack, but a _SetTrapAddress patch
\ seems to be removed under Multifinder
\ J. Langowski / MacTutor April 1989
only forth also mac also assembler
( *** compiler support words for external definitions *** )
: :xdef
create -4 allot
$4EFA w, ( JMP )
0 w, ( entry point to be filled later )
0 , ( length of routine to be filled later )
here 6 - 76543
;
: ;xdef { branch marker entry | -- }
marker 76543 <> abort" xdef mismatch"
entry branch - branch w!
here branch - 2+ branch 2+ !
;
: xlen 4 + @ ; ( get length word of external definition )
\ **** ext procedure glue macros
CODE ext.prelude
LINK A6,#-700 ( 700 bytes of local Forth stack )
MOVEM.L A0-A5/D0-D7,-(A7) ( save registers )
MOVE.L A6,A3 ( setup local loop return stack )
SUBA.L #500,A3 ( in the low 200 local stack bytes )
RTS \ just to indicate the MACHro stops here
END-CODE MACH
CODE ext.epilogue
MOVEM.L (A7)+,A0-A5/D0-D7 ( restore registers )
UNLK A6
RTS
END-CODE MACH
.trap _newPtr,SYS $A51E
-4 CONSTANT thePort
$904 CONSTANT CurrentA5
$A9A0 CONSTANT tGetRes \ GetResource
$A9F4 CONSTANT tExit \ ExitToShell
\ |--------------------------------|
\ | INIT resource code starts here |
\ |--------------------------------|
:xdef beeperINIT
header PatchStart
header oldGetRes
DC.L 0
header oldExit
DC.L 0
: GetResPatch
ext.prelude
CLR.L D0
MOVE.W 8(A6),D0
MOVE.L 10(A6),D1
MOVE.L D0,-(A6)
MOVE.L D1,-(A6)
\ main FORTH code starts here
\ this can be used to log any launch
\ (i.e. GetResource CODE 0 ) to a log file
\ which has to be created/opened by the INIT code
ascii CODE = swap 0= and IF
\ (call) debugger
1 (call) sysbeep
THEN
\ end of main code
ext.epilogue
LEA oldGetRes,A0
MOVE.L (A0),A0
JMP (A0)
;
: ExitPatch
ext.prelude
\ main FORTH code starts here
\ this can eventually be used to write a line to
\ the same log file as before
\ (call) debugger
1 (call) sysbeep
\ end of main code
ext.epilogue
LEA oldExit,A0
MOVE.L (A0),A0
JMP (A0)
;
header PatchEnd
: movePatch { | length -- patch }
['] patchEnd ['] PatchStart - -> length
length
MOVE.L (A6)+,D0
_newPtr,sys
MOVE.L A0,-(A6)
dup IF ( we have space in system heap )
['] PatchStart over length swap (call) blockMove drop
THEN
;
: myINIT { | patch pExit -- }
movePatch -> patch
patch IF
\ patch _GetResource
tGetRes (call) GetTrapAddress
patch ! \ old GetResource
['] GetResPatch ['] PatchStart -
patch + tGetRes (call) SetTrapAddress
" GetResource patch has been installed." 0 0 0 (call) ParamText
1000 0 (call) NoteAlert drop
\ patch _ExitToShell, using hack
tExit (call) GetTrapAddress -> pExit
pExit w@ $4EF9 =
IF \ is it a JMP ? we're probably in Multifinder...
pExit 2+ @
patch 4+ ! \ old ExitToShell
['] ExitPatch ['] PatchStart -
patch + pExit 2+ !
\ patch directly into Juggler's innards. BOO!
" ExitToShell patch in Multifinder." 0 0 0 (call) ParamText
1000 0 (call) NoteAlert drop
ELSE
pExit patch 4+ !
['] ExitPatch ['] PatchStart -
patch + tExit (call) SetTrapAddress
" ExitToShell patch in Finder." 0 0 0 (call) ParamText
1000 0 (call) NoteAlert drop
THEN
ELSE
" Can't get memory for patches." 0 0 0 (call) ParamText
1000 0 (call) NoteAlert drop
THEN
;
: INITrun { | newA5 myGlobals [ 202 lallot ] theHandle -- }
\ (call) debugger
['] beeperINIT (call) recoverHandle -> theHandle
theHandle (call) Hlock drop
^ newA5
MOVE.L (A6)+,A5 \ create area for QD globals
MOVE.L A5,CurrentA5 \ A5 points to it
^ newA5 thePort + (call) InitGraf
(call) InitFonts
(call) InitWindows
(call) TEInit
0 (call) InitDialogs
(call) InitCursor
myINIT \ call main INIT routine
theHandle (call) HUnLock drop
theHandle (call) DisposHandle drop
;
: gINIT
ext.prelude INITrun ext.epilogue
MOVE.L A5,CurrentA5
;
' gINIT ;xdef
( *** creating the INIT file *** )
: $create-res call CreateResFile call ResError L_ext ;
: $open-res { addr | refNum -- result }
addr call openresfile -> refNum
call ResError L_ext
dup not IF drop refNum THEN
;
: $close-res call CloseResFile call ResError L_ext ;
: make-init { | refNum -- }
" theINIT" dup $create-res drop
$open-res dup -> refNum call UseResFile
ascii INIT 12 call GetResource
?dup IF call RmveResource THEN
['] beeperINIT dup xlen
call PtrToHand drop ( result code )
ascii INIT 12 call GetResource
?dup IF call RmveResource THEN
ascii INIT 12 " Beeper" call AddResource
refNum $close-res drop ( result code )
;